﻿using Microsoft.Xna.Framework;
using Rescue_of_the_Dwarvenzombies.SceneLayers;
using Rescue_of_the_Dwarvenzombies.Scene;

namespace Rescue_of_the_Dwarvenzombies.SceneObjects.GameObjects.Characters.Enemies
{
    public class AI
    {
        private static AI _instance;

        /// <summary>
        /// Gets or sets the player layer.
        /// </summary>
        /// <value>
        /// The player layer.
        /// </value>
        public ISceneLayer PlayerLayer { get; set; }

        /// <summary>
        /// Gets or sets the enemy layer.
        /// </summary>
        /// <value>
        /// The enemy layer.
        /// </value>
        public ISceneLayer EnemyLayer { get; set; }

        /// <summary>
        /// Gets or sets the obstacle layer.
        /// </summary>
        /// <value>
        /// The obstacle layer.
        /// </value>
        public ISceneLayer ObstacleLayer { get; set; }

        /// <summary>
        /// Gets or sets the game.
        /// </summary>
        /// <value>
        /// The game.
        /// </value>
        public Game Game { get; set; }

        /// <summary>
        /// Prevents a default instance of the <see cref="AI"/> class from being created.
        /// </summary>
        private AI() {}

        /// <summary>
        /// Instances this instance.
        /// </summary>
        /// <returns></returns>
        public static AI Instance()
        {
            return _instance ?? (_instance = new AI());
        }

        /// <summary>
        /// Gets the AI move by first finding the nearest player then persuing 
        /// that player if no enemy is closer than a said distance. If two enemies 
        /// are too close the coliding enemy will take the opposite direction of the
        /// other enemy
        /// </summary>
        /// <param name="currentEnemyPosition">The current enemy position.</param>
        /// <returns></returns>
        public Vector2 GetAIMove(Vector2 currentEnemyPosition)
        {
            Vector2 move = new Vector2(), evade = new Vector2();
            float distance = 1000000, temp;

            //Decide which Player the Enemy should persue
            foreach (var player in PlayerLayer.GetSceneObjects())
            {
                temp = Vector2.Distance(player.Position, currentEnemyPosition);
                if (distance > temp)
                {
                    distance = temp;
                    move = player.Position - currentEnemyPosition;
                    move.Normalize();
                }
            }
            
            //Checks if the Enemy should follow the Player or evade the object (only enemies implemented)
            return ((IPhysicsManager)Game.Services.GetService(typeof(IPhysicsManager))).PossibleMove(EnemyLayer, ObstacleLayer, ref evade, currentEnemyPosition) ? move : evade;
        }
    }
}






